﻿using Domain.Entitys.Inv;
using Domain.IRepositorys.Inv;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.CompilerServices.RuntimeHelpers;

namespace EFCore.Repositorys.Inv
{
    public class Inv_QtyRepository : IInv_QtyRepository
    {

        private readonly MyDbContext myDbContext;

        public Inv_QtyRepository(MyDbContext myDbContext)
        {
            this.myDbContext = myDbContext;
        }


        /// <summary>
        /// 删除盘点单
        /// </summary>
        /// <param name="qty_id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_Qty_delete(int qty_id)
        {
            var query = await myDbContext.inv_qty.Where(x => x.Qty_id == qty_id).FirstOrDefaultAsync();

            if (query == null)
            {
                throw new Exception("未找到对应的仓库调拨单");
            }
            query.Del_flag = '1';

            return await myDbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 修改审核状态
        /// </summary>
        /// <param name="inv_qty"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_Qty_examineUpdate(Inv_qty inv_qty)
        {
            var qry = await myDbContext.inv_qty.Where(e => e.Qty_code == inv_qty.Qty_code).FirstOrDefaultAsync();
            if (qry == null)
            {

                throw new Exception("未找到对应的入库单");
            }
            // 更新审核信息
            qry.qty_audit_by = inv_qty.qty_audit_by;
            qry.qty_audit_status = inv_qty.qty_audit_status; // 如果传的是字符串
            qry.qty_audit_time = inv_qty.qty_audit_time;
            qry.qty_audit_opinion = inv_qty.qty_audit_opinion;

            // 保存更改
            return await myDbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 根据编号查询盘点主表
        /// </summary>
        /// <param name="qty_code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<List<Inv_qty>> Inv_Qty_SelectCode(string qty_code)
        {
            var query = myDbContext.inv_qty.Where(x => x.Del_flag == '0' && x.Qty_code == qty_code).ToListAsync();
            return query;
        }
        /// <summary>
        /// 盘点查询总数
        /// </summary>
        /// <param name="qty_code"></param>
        /// <param name="qty_type"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<int> Inv_Qty_selectCount(string qty_code, string qty_type, string proName)
        {
            var query = myDbContext.inv_qty.AsQueryable();

            query = query.Where(x => x.Del_flag == '0');

            // 条件1: 入库类型筛选（如果提供了）
            if (!string.IsNullOrEmpty(qty_code))
            {
                query = query.Where(x => x.Qty_code == qty_code);
            }

            // 条件2: 关键字搜索（如果提供了）
            if (!string.IsNullOrEmpty(qty_type))
            {
                query = query.Where(x => x.Qty_type == qty_type);

            }
            if (!string.IsNullOrEmpty(proName))
            {
                var details = myDbContext.inv_proddti
                    .Where(d => d.Pro_name.Contains(proName) || d.Pro_code.Contains(proName))
                    .Select(d => d.Qty_id);
                query = query.Where(q => details.Contains(q.Qty_id));
            }
            // 统计总数
            return query.CountAsync();
        }
        /// <summary>
        /// 返回盘点明细
        /// </summary>
        /// <param name="qty_code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<inv_proddti>> Inv_Qty_SelectDetail(string qty_code)
        {
            var query = await myDbContext.inv_qty.Where(x => x.Del_flag == '0' && x.Qty_code == qty_code).FirstOrDefaultAsync();

            if (query == null)
            {
                throw new Exception("盘点单不存在");
            }

            var inv_proddti = await myDbContext.inv_proddti.Where(x => x.Qty_id == query.Qty_id).ToListAsync();

            return inv_proddti;
        }
        /// <summary>
        ///分页查询
        /// </summary>
        /// <param name="qty_code"></param>
        /// <param name="qty_type"></param>
        /// <param name="currentPage"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<Qty_SelectDto> Inv_Qty_selectFY(string qty_code, string qty_type, int currentPage, int pageSize, string proName)
        {
            // 使用 IQueryable 延迟构建查询
            IQueryable<Inv_qty> query = myDbContext.inv_qty;

            query = query.Where(x => x.Del_flag == '0');

            // 条件1: 入库类型筛选（如果提供了）
            if (!string.IsNullOrEmpty(qty_code))
            {
                query = query.Where(x => x.Qty_code == qty_code);
            }

            // 条件2: 关键字搜索（如果提供了）
            if (!string.IsNullOrEmpty(qty_type))
            {
                query = query.Where(x => x.Qty_type == qty_type);

            }

            query = query.OrderByDescending(d => d.Create_time);

            if (!string.IsNullOrEmpty(proName))
            {
                var details = myDbContext.inv_proddti
                    .Where(d => d.Pro_code.Contains(proName) || d.Pro_name.Contains(proName))
                    .Select(d => d.Qty_id);
                query = query.Where(q => details.Contains(q.Qty_id));
            }

            var result = query
             .Skip((currentPage - 1) * pageSize)
             .Take(pageSize)
             .Select(main => new Qty_SelectDto
             {
                 Qty_id = main.Qty_id,
                 Qty_type = main.Qty_type,
                 Qty_code = main.Qty_code,
                 Qty_startdate = main.Qty_startdate,
                 Qty_end = main.Qty_end,       // 新增盘点结束时间
                 Qty_clerk = main.Qty_clerk,   // 新增盘点人员
                 Warehouse_code = main.Warehouse_code,
                 Warehouse_name = main.Warehouse_name,
                 qty_audit_status= main.qty_audit_status,
                 qty_audit_opinion= main.qty_audit_opinion,
                 Details = main.Details.Select(detail => new Qty_SelectDto.InvProddti
                 {
                     Qty_id = detail.Qty_id,
                     Pro_name = detail.Pro_name,
                     Pro_code = detail.Pro_code,
                     Pro_brand = detail.Pro_brand,
                     Pro_model = detail.Pro_model,
                     Unitmeas_id = detail.Unitmeas_id,
                     Pro_cost_price = detail.Pro_cost_price,
                     Pro_sale_price = detail.Pro_sale_price,
                     Location_code = detail.Location_code,
                     Location_name = detail.Location_name,
                     Inventory_numder = detail.Inventory_numder,
                     Proddti_loss = detail.Proddti_loss,     // 新增盘亏数量
                     Proddti_profit = detail.Proddti_profit  // 新增盘盈数量
                 }).ToList()
             })
             .ToList();

            return result;
        }
        /// <summary>
        /// 添加盘点单
        /// </summary>
        /// <param name="inv_qty"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_trf_Insert(Inv_qty inv_qty)
        {
          await myDbContext.inv_qty.AddAsync(inv_qty);
            return await myDbContext.SaveChangesAsync();
        }



        /// <summary>
        /// 添加盘点明细
        /// </summary>
        /// <param name="inv_proddtiList"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> inv_proddti_Insert(List<inv_proddti> inv_proddtiList)
        {
           await myDbContext.inv_proddti.AddRangeAsync(inv_proddtiList); 
            return await myDbContext.SaveChangesAsync();
        }
        /// <summary>
        /// 根据编号查询ID，
        /// </summary>
        /// <param name="Qty_code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> inv_Qty_id(string Qty_code)
        {
            var query = await myDbContext.inv_qty.FirstOrDefaultAsync(x => x.Qty_code == Qty_code&&x.Del_flag=='0');
            return query.Qty_id;
        }
        /// <summary>
        /// 修改盘点单和详细盘点单
        /// </summary>
        /// <param name="inv_Qty"></param>
        /// <param name="inv_Proddtis"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_Qty_Update(Inv_qty inv_Qty, List<inv_proddti> inv_Proddtis)
        {
            using var transaction = await myDbContext.Database.BeginTransactionAsync();
            try
            {
                // 1. 更新主表信息
                var existingOrder = await myDbContext.inv_qty
                    .FirstOrDefaultAsync(o => o.Qty_id == inv_Qty.Qty_id);

                if (existingOrder == null)
                {
                    throw new Exception($"盘点单 {inv_Qty.Qty_code} 不存在");
                }

                // 更新允许修改的字段
                existingOrder.Qty_type = inv_Qty.Qty_type;
                existingOrder.Qty_startdate = inv_Qty.Qty_startdate;
                existingOrder.Qty_end = inv_Qty.Qty_end;
                existingOrder.Warehouse_code = inv_Qty.Warehouse_code;
                existingOrder.Warehouse_name = inv_Qty.Warehouse_name;
                existingOrder.Zone_code = inv_Qty.Zone_code;
                existingOrder.Zone_name = inv_Qty.Zone_name;
                existingOrder.Update_by = inv_Qty.Update_by;
                existingOrder.Update_time = inv_Qty.Update_time;

                myDbContext.Update(existingOrder);
                await myDbContext.SaveChangesAsync();

                // 2. 获取现有明细
                var existingDetails = await myDbContext.inv_proddti
                    .Where(d => d.Qty_id == existingOrder.Qty_id)
                    .ToListAsync();

                // 3. 识别三类记录
                var toAdd = new List<inv_proddti>();
                var toUpdate = new List<inv_proddti>();
                var toDeleteIds = new List<int>();

                // 处理传入的新明细
                foreach (var newItem in inv_Proddtis)
                {
                    // 新增记录：ID为0或不在现有明细中
                    if (newItem.Proddti_id == 0 ||
                        !existingDetails.Any(d => d.Proddti_id == newItem.Proddti_id))
                    {
                        toAdd.Add(newItem);
                    }
                    // 更新记录：ID存在且字段有变化
                    else
                    {
                        var existingItem = existingDetails
                            .First(d => d.Proddti_id == newItem.Proddti_id);

                        if (IsQtyDetailModified(existingItem, newItem))
                        {
                            toUpdate.Add(newItem);
                        }
                    }
                }

                // 识别需要删除的记录
                toDeleteIds = existingDetails
                    .Where(d => !inv_Proddtis.Any(e => e.Proddti_id == d.Proddti_id))
                    .Select(d => d.Proddti_id)
                    .ToList();

                if (toDeleteIds.Any())
                {
                    var deleteItems = existingDetails
                        .Where(d => toDeleteIds.Contains(d.Proddti_id))
                        .ToList();

                    myDbContext.RemoveRange(deleteItems);
                }

                // 4.2 更新变化的明细
                foreach (var item in toUpdate)
                {
                    var existingItem = existingDetails
                        .First(d => d.Proddti_id == item.Proddti_id);

                    // 更新允许修改的字段
                    existingItem.Pro_name = item.Pro_name;
                    existingItem.Pro_code = item.Pro_code;
                    existingItem.Pro_brand = item.Pro_brand;
                    existingItem.Unitmeas_id = item.Unitmeas_id;
                    existingItem.Pro_model = item.Pro_model;
                    existingItem.Pro_cost_price = item.Pro_cost_price;
                    existingItem.Pro_sale_price = item.Pro_sale_price;
                    existingItem.Location_code = item.Location_code;
                    existingItem.Location_name = item.Location_name;
                    existingItem.Inventory_numder = item.Inventory_numder;
                    existingItem.Proddti_loss = item.Proddti_loss;
                    existingItem.Proddti_profit = item.Proddti_profit;
                    existingItem.Proddti_profit_money = item.Proddti_profit_money;
                    existingItem.Proddti_loss_money = item.Proddti_loss_money;

                    myDbContext.Update(existingItem);
                }

                // 4.3 添加新明细
                foreach (var item in toAdd)
                {
                    item.Qty_id = existingOrder.Qty_id;
                    await myDbContext.AddAsync(item);
                }

                await myDbContext.SaveChangesAsync();
                await transaction.CommitAsync();

                return 1;
            }
            catch (Exception ex)
            {
                await transaction.RollbackAsync();
                // 记录日志
                // logger.LogError(ex, "更新盘点单失败");
                return 0;
            }
        }

        // 辅助方法：检查盘点单明细是否被修改
        private bool IsQtyDetailModified(inv_proddti existing, inv_proddti updated)
        {
            return existing.Pro_name != updated.Pro_name ||
                   existing.Pro_code != updated.Pro_code ||
                   existing.Pro_brand != updated.Pro_brand ||
                   existing.Unitmeas_id != updated.Unitmeas_id ||
                   existing.Pro_model != updated.Pro_model ||
                   existing.Pro_cost_price != updated.Pro_cost_price ||
                   existing.Pro_sale_price != updated.Pro_sale_price ||
                   existing.Location_code != updated.Location_code ||
                   existing.Location_name != updated.Location_name ||
                   existing.Inventory_numder != updated.Inventory_numder ||
                   existing.Proddti_loss != updated.Proddti_loss ||
                   existing.Proddti_profit != updated.Proddti_profit ||
                   existing.Proddti_profit_money != updated.Proddti_profit_money ||
                   existing.Proddti_loss_money != updated.Proddti_loss_money;
        }

        /// <summary>
        /// 查询盘点单信息--其他入库单
        /// </summary>
        /// <param name="code"></param>
        /// <param name="currentPage"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<Inv_qty> Inv_Qty_MainSelect(string code, int currentPage, int pageSize)
        {
            var query = myDbContext.inv_qty
          .Include(q => q.Details)               // 加载明细
          .Where(x => x.Del_flag == '0'
                      && x.qty_audit_status == '1'
                      && x.qty_store == '0'      // 未入库
                      && x.Details.Any(d => d.Proddti_profit > 0)); // 至少一条盘盈

            if (!string.IsNullOrEmpty(code))
                query = query.Where(x => x.Qty_code.Contains(code));

            return query
                .OrderByDescending(x => x.Qty_id)
                .Skip((currentPage - 1) * pageSize)
                .Take(pageSize)
                .ToList();
        }
        /// <summary>
        /// 查询盘点单信息总数--其他入库单
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async  Task<int> Inv_Qty_MainSelect_Count(string code)
        {
            var query = myDbContext.inv_qty
                  .Where(x => x.Del_flag == '0'
                           && x.qty_audit_status == '1'
                           && x.qty_store == '0'
                           && x.Details.Any(d => d.Proddti_profit > 0));

            if (!string.IsNullOrEmpty(code))
                query = query.Where(x => x.Qty_code.Contains(code));

            // ✅ 使用异步 CountAsync
            return await query.CountAsync();

        }
        /// <summary>
        /// 查询盘点单的详细信息--其他入库单
        /// </summary>
        /// <param name="qty_code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public  async Task<List<inv_proddti>> Inv_Qty_SelectMainDetail(string qty_code)
        {

            // 验证输入参数
            if (string.IsNullOrWhiteSpace(qty_code))
            {
                throw new ArgumentException("盘点单号不能为空", nameof(qty_code));
            }

            // 获取对应的盘点主单
            var qty = await myDbContext.inv_qty
                .Where(x => x.Del_flag == '0' && x.Qty_code == qty_code)
                .FirstOrDefaultAsync();

            if (qty == null)
            {
                throw new Exception($"未找到盘点单号 '{qty_code}' 对应的仓库盘点单");
            }

            // 查询只有盘盈数量的产品明细
            var profitOnlyDetails = await myDbContext.inv_proddti
                .Where(x => x.Qty_id == qty.Qty_id &&
                           x.Proddti_profit > 0 &&
                           x.Proddti_loss <= 0) // 盘亏数量小于等于0
                .ToListAsync();

            return profitOnlyDetails;
        }
      



        /// <summary>
        /// 修改状态
        /// </summary>
        /// <param name="inv_Proddtis"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_Qty_Update_zt(List<inv_proddti> inv_Proddtis)
        {
            // 查询对应的Inv_qty记录
            var invQty = await myDbContext.inv_qty
                .Include(q => q.Details) // 包含明细
                .FirstOrDefaultAsync(q => q.qty_store == '0' && q.qty_audit_status == '1'); //假设初始状态为未入库且已审核

            if (invQty == null)
            {
                throw new Exception("未找到符合条件的库存盘点记录。");
            }

            // 根据产品编码、库位编码和关联单号查询对应的inv_proddti记录
            foreach (var item in inv_Proddtis) {

                var qurey = await myDbContext.inv_proddti.FirstOrDefaultAsync(s => s.Pro_code == item.Pro_code && s.stock_entry_no == item.stock_entry_no && s.Location_code == item.Location_code && s.Qty_id == invQty.Qty_id);

                if (qurey == null)
                {
                    throw new Exception("未找到对应的库存盘点明细。");
                }

                var inv_qty=myDbContext.inv_qty.Where(x => x.Qty_id == qurey.Qty_id).FirstOrDefault();

                if (inv_qty == null)
                {
                    throw new Exception("未找到对应的库存盘点记录。");
                }
                inv_qty.qty_store = '1';

            }
            // 保存更改
           return await myDbContext.SaveChangesAsync();

           
        }
        /// <summary>
        /// 查询盘点单--盘亏出库--查询不合格数量的产品
        /// </summary>
        /// <param name="code"></param>
        /// <param name="currentPage"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<Inv_qty> Inv_Qty_Maisbhg_Select(string code, int currentPage, int pageSize)
        {
            // 1. 先筛选出已审核、未做“盘亏出库”的盘点单
            var query = myDbContext.inv_qty
                .Where(q => q.Del_flag == '0'
                            && q.qty_audit_status == '1'
                            && q.qty_store_bhg == '0');

            // 2. 再限定：只要这些盘点单里“至少有一条明细的盘亏数量>0”
            query = query.Where(q => myDbContext.inv_proddti
                                    .Any(d => d.Qty_id == q.Qty_id && d.Proddti_loss > 0));

            // 3. 按单号精确过滤
            if (!string.IsNullOrEmpty(code))
                query = query.Where(q => q.Qty_code == code);

            // 4. 分页返回
            return query.OrderByDescending(q => q.Qty_id)
                        .Skip((currentPage - 1) * pageSize)
                        .Take(pageSize)
                        .ToList();
        }
        /// <summary>
        ///查询盘点单总数--盘亏出库--查询不合格数量的产品
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> Inv_Qty_Maisbhg_Select_Count(string code)
        {
            // 1. 先筛选出已审核、未做“盘亏出库”的盘点单
            var query = myDbContext.inv_qty
                .Where(q => q.Del_flag == '0'
                            && q.qty_audit_status == '1'
                            && q.qty_store_bhg == '0');

            // 2. 再限定：只要这些盘点单里“至少有一条明细的盘亏数量>0”
            query = query.Where(q => myDbContext.inv_proddti
                                    .Any(d => d.Qty_id == q.Qty_id && d.Proddti_loss > 0));

            // 3. 按单号精确过滤
            if (!string.IsNullOrEmpty(code))
                query = query.Where(q => q.Qty_code == code);

            return await query.CountAsync();
        }
        /// <summary>
        /// 查询盘点单的详情--盘亏出库--查询不合格数量的产品
        /// </summary>
        /// <param name="qty_code"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<inv_proddti>> Inv_Qty_SelectMainbhgDetail(string qty_code)
        {
            // 验证输入参数
            if (string.IsNullOrWhiteSpace(qty_code))
            {
                throw new ArgumentException("盘点单号不能为空", nameof(qty_code));
            }

            // 获取对应的盘点主单
            var qty = await myDbContext.inv_qty
                .Where(x => x.Del_flag == '0' && x.Qty_code == qty_code)
                .FirstOrDefaultAsync();

            if (qty == null)
            {
                throw new Exception($"未找到盘点单号 '{qty_code}' 对应的仓库盘点单");
            }

            // 查询只有盘盈数量的产品明细
            var profitOnlyDetails = await myDbContext.inv_proddti
                .Where(x => x.Qty_id == qty.Qty_id &&
                           x.Proddti_loss > 0 &&
                           x.Proddti_profit <= 0) // 盘盈数量小于等于0
                .ToListAsync();

            return profitOnlyDetails;
        }



        /// <summary>
        /// 其他出库单审核完毕之后,修改盘点单的qty_store_bhg这个字段为1
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
      
        public Task<int> Inv_qty_update_qty_store_bhg(string code)
        {
            var query=myDbContext.inv_qty.Where(x=>x.Qty_code==code).FirstOrDefault();
            if (query == null) { 
            
               throw new Exception ("未找到对应的盘点单。");
            }
            query.qty_store_bhg = '1';
            return myDbContext.SaveChangesAsync();
        }
    }
}
